package generator.workflow.sfj.gridgain;

import generator.datastructure.MethodDeclaration;
import generator.datastructure.WritebleClass;
import generator.util.input_interpreter.SpringBeanPolicyInterpreter;
import generator.workflow.PolicyManager;

public abstract class GridGainPolicyManager extends PolicyManager {

	private WritebleClass peerWithPolicies = null;
	
	@Override
	protected void addApplicationPolicies(MethodDeclaration md,	WritebleClass peerClass) {		
			this.insertPolicyManagerInstance(peerClass);
			this.insertPoliciesInicializationMethod(((SpringBeanPolicyInterpreter)policyInterpreter).getSpringBeanPoliciesFile(md),md, peerClass);
			String instanceName = this.insertAppPolicyInicialization(((SpringBeanPolicyInterpreter)policyInterpreter).getAppPolicyBeanID(md), md, peerClass);			
			this.insertAppPolicyInvocation(instanceName, md, peerClass);
			this.peerWithPolicies = peerClass;
	}	

	
	@Override
	protected void addMiddlewarePolicies(MethodDeclaration methodToParallelize, WritebleClass peerClass) {
		String balancerPolicyInstanceName = this.declareLoadBalancerPolicy(peerClass, methodToParallelize);
		this.initCustomLoadBalancer(((SpringBeanPolicyInterpreter)policyInterpreter).getBalancerPolicyBeanID(methodToParallelize),methodToParallelize, peerClass, balancerPolicyInstanceName);
		
		String granPolicyInstanceName = this.declareGranularityPolicy(peerClass,methodToParallelize);
		this.initCustomGranularityPolicy(((SpringBeanPolicyInterpreter)policyInterpreter).getGranularityPolicyBeanID(methodToParallelize),methodToParallelize, peerClass, granPolicyInstanceName);
		peerWithPolicies = peerClass;
	}	

	protected abstract void initCustomGranularityPolicy(String granPolicyBeanId, MethodDeclaration methodToParallelize, WritebleClass peerClass, String granPolicyInstanceName);

	protected abstract String declareGranularityPolicy(WritebleClass peerClass, MethodDeclaration md);

	protected abstract void initCustomLoadBalancer(String balancerPolicyBeanId, MethodDeclaration methodToParallelize, WritebleClass peerClass, String balancerPolicyInstanceName);

	protected abstract String declareLoadBalancerPolicy(WritebleClass peerClass, MethodDeclaration methodToParallelize);

	/**Inserta en la clase peer la sentencia de inicialización del contexto Spring pasando como parámetro
	 * el archivo que contiene la declaración de los POJO's de las políticas.
	 * Un ejemplo de la sentencia que debe insertarse es:<BR>
	 *FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext(policiesFile.xml);
	 * @param springBeanPoliciesFile
	 * 			contiene la ruta del archivo que debe incluirse como parámetro en la creación del objeto
	 * 			{@link org.springframework.context.support.FileSystemXmlApplicationContext}.
	 * 			En el ejemplo provisto corresponde al parámetro "policiesFile.xml"
	 * @param md 
	 * 			método sobre el cual se está insertando las políticas.
	 * @param peerClass 
	 * @return nombre que se le ha dado a la instancia del objeto {@link org.springframework.context.support.FileSystemXmlApplicationContext}.
	 * 			Para el ejemplo retornaría "ctx"   
	 * */
	protected abstract void insertPolicyManagerInstance(WritebleClass peerClass);
	
	protected abstract void insertPoliciesInicializationMethod(String springBeanPoliciesFile, MethodDeclaration md,	WritebleClass peerClass);

	protected abstract void insertAppPolicyInvocation(String instanceName, MethodDeclaration md, WritebleClass peerClass);

	protected abstract String insertAppPolicyInicialization(String politicBeanID, MethodDeclaration md, WritebleClass peerClass);
		

	@Override
	protected WritebleClass getPeerWithPolicies() {
		return peerWithPolicies;
	}

}
